﻿using WCS.Entity;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WcsTask.DevCommTaks;
using System.Configuration;
using Newtonsoft.Json;
using System.Reflection;
using WCS.Utils;
using WCS;
using WcsTask.Routes;
using WCS.WebRequest;
using WCS.Controls.RunLog;
using System.Linq;
using WCS.Helpers;
using Sunny.UI;
using System.Diagnostics;
using WCS.Entity.SYS;
using static System.Collections.Specialized.BitVector32;
using System.Collections;
using static System.Runtime.CompilerServices.RuntimeHelpers;
using WCS.Entity.MES;
using WCS.Helpers.PLCOperation;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Net;

namespace WcsTask
{
    /// <summary>
    /// 任务处理实体
    /// </summary>
    public class ProcessingTaskMain
    {
        private ProcessingTaskMain() { }

        private static readonly ProcessingTaskMain processingTaskMain = new ProcessingTaskMain();

        public static ProcessingTaskMain _processingTaskMain
        {
            get
            {
                return processingTaskMain;
            }
        }

        static object _lock = new object();

        /// <summary>
        /// 取日期数  "2022221"
        /// </summary>
        static string _prefix;

        /// <summary>
        /// 数据库连接对象
        /// </summary>
        static SqlSugarDapper _SqlSugarDapper = SqlSugarDapper.GetDbContext();

        /// <summary>
        /// 仿真模式
        /// </summary>
        string _simulation = ConfigurationManager.AppSettings["simulation"];

        /// <summary>
        /// WCS向WMS上报任务完成
        /// </summary>
        string _TaskComplete = ConfigurationManager.AppSettings["TaskComplete"];
        string _LAY = ConfigurationManager.AppSettings["LAY"];

        /// <summary>
        /// WCS向WMS请求任务
        /// </summary>
        string _RequestTask = ConfigurationManager.AppSettings["RequestTask"];

        /// <summary>
        /// WCS向WMS请求任务
        /// </summary>
        public string _ControlA006 = "1";

        /// <summary>
        /// WCS向WMS请求任务
        /// </summary>
        public string _ControlA002 = "1";

        /// <summary>
        /// AGV任务下发接口
        /// </summary>
        readonly string _MES = ConfigurationManager.AppSettings["MES"];

        /// <summary>
        /// 日志模块
        /// </summary>
        string _modular = "【主任务模块】";

        /// <summary>
        /// 砂芯缓存站台
        /// </summary>
        public List<string> SandCoreBufferStation;

        /// <summary>
        /// 砂芯站台
        /// </summary>
        public List<string> SandCoreStation;

        /// <summary>
        /// 铸造站台集合
        /// </summary>
        public List<string> castingStations = new List<string>();

        /// <summary>
        /// 质检站台
        /// </summary>
        public List<string> qualityTestingStation;

        /// <summary>
        /// 入库标识
        /// </summary>
        public bool _InFlag = false;

        /// <summary>
        /// 出库标识
        /// </summary>
        public bool _OutnFlag = false;

        /// <summary>
        /// WCS任务集合
        /// </summary>
        public List<WcsTaskMain> _wcsTaskMains
        {
            get
            {
                var wcsTaskMainList = _SqlSugarDapper.DB.Queryable<WcsTaskMain>()
                    .OrderBy(w => w.Priority, OrderByType.Desc)//首先根据优先级排序   优先级越大月优先
                    .OrderBy(w => w.CreateTime)//然后根据创建时间排序
                    .OrderBy(w => w.Order)//最后根据任务先后顺序排序
                    .ToList();

                foreach (var wcsTaskMain in wcsTaskMainList)
                {
                    wcsTaskMain.wcsTaskConveyor = _SqlSugarDapper.DB.Queryable<WcsTaskConveyor>()
                        .Where(w => w.Task_Code == wcsTaskMain.Task_Code)
                        .OrderBy(w => w.CreateTime)//根据任务先后顺序排序
                        .First();

                    wcsTaskMain.wcsTaskAGVs = _SqlSugarDapper.DB.Queryable<WcsTaskAGV>()
                        .Where(w => w.Task_Code == wcsTaskMain.Task_Code)
                        .OrderBy(w => w.indexOrder)//根据任务先后顺序排序
                        .ToList();
                }

                return wcsTaskMainList;
            }
        }

        //var Address = $"{MethodBase.GetCurrentMethod().Name}      (WMS给WCS下发任务)";
        //var asd = new StackTrace().GetFrame(0).GetMethod().Name;
        //var asdw = new StackTrace().GetFrame(1).GetMethod().Name;

        public static int bytesToInt(byte[] src, int offset = 0)
        {
            int value;
            value = (int)(((src[offset] & 0xFF) << 24)
                    | ((src[offset + 1] & 0xFF) << 16)
                    | ((src[offset + 2] & 0xFF) << 8)
                    | (src[offset + 3] & 0xFF));
            return value;
        }

        /// <summary>
        /// 任务初始化方法
        /// </summary>
        public void Initial()
        {
            ProcessingTaskMain.GenerateRandomCode("main");

            //获取当前层数的最后Index
            //var i = WarehouseInfo.GetWarehouseInfoIndex("9001-2");
            //Warehouse.GetWarehouseByMaterialTypeOut11(1, "X03后副车架砂芯");
            //Warehouse.GetWarehouseByMaterialTypeIn(1, "X03后副车架砂芯");

            //路径初始化
            RouteSet.routeSet.RouteInit();

            castingStations = PlcDev._plcDev.ConveyorStationList.FindAll(f => f.Station_Name == "铸造缓存").Select(s => s.Station_Plc_No).ToList();
            SandCoreBufferStation = PlcDev._plcDev.ConveyorStationList.FindAll(f => f.Station_Name.Contains("砂芯缓存")).Select(s => s.Station_Plc_No).ToList();
            SandCoreStation = PlcDev._plcDev.ConveyorStationList.FindAll(f => f.Station_Name.Contains("制砂芯")).Select(s => s.Station_Plc_No).ToList();
            qualityTestingStation = PlcDev._plcDev.ConveyorStationList.FindAll(f => f.Station_Name.Contains("质检")).Select(s => s.Station_Plc_No).ToList();

            //运行线程 去读任务
            Task.Run(() => ProcessTask());

            //Task.Run(() => StackerTask._stackerTask.StackerProcessTask());

            Task.Run(() => ConveyorTask._conveyorTask.Init());

            Task.Run(() => AGVTask._agvTask.Init());

            //运行线程 读取条码
            Task.Run(() => ReadTrayCode());
        }

        /// <summary>
        /// 处理任务--线程
        /// </summary>
        private void ProcessTask()
        {
            while (true)
            {
                try
                {
                    foreach (var wcsTaskMain in _wcsTaskMains.FindAll(t => t.Task_State != (int)Task_State.执行中 && t.Task_State != (int)Task_State.等待执行 || t.Split == 1))
                    {
                        if (wcsTaskMain.Task_State == (int)Task_State.任务取消)
                        {
                            ConveyorTask._conveyorTask.DeleteConveyTask(wcsTaskMain.Task_Code, "任务已取消");
                            AGVTask._agvTask.DeleteAGVTask(wcsTaskMain.Task_Code, "任务已取消");

                            DeleteMainTask(wcsTaskMain.Id, "任务取消,删除任务");

                            RunLog.runLog.Debug($"{_modular}任务取消,删除任务，任务号:【{wcsTaskMain.Task_Code}】");
                            continue;
                        }

                        //初始状态开始拆分任务
                        if (wcsTaskMain.Split == 1)
                        {
                            SplitTaskMain(wcsTaskMain);
                        }
                        //if (wcsTaskMain.Split == 1&&PlcDev._plcDev.conveyorReadData.AllowBOne==true&&wcsTaskMain.Start_Station=="B001")
                        //{
                        //    SplitTaskMain(wcsTaskMain);
                        //}
                        if (wcsTaskMain.Task_State == (int)Task_State.上报WMS任务完成)
                        {
                            if (wcsTaskMain.Task_Source == (int)Task_Source.WMS下发任务)
                            {
                                var obj = new
                                {
                                    trayCode = wcsTaskMain.TrayBar_Code,
                                    taskCode = wcsTaskMain.Task_Code
                                };
                                RunLog.runLog.Debug($"{_modular}准备向WMS上报任完成，任务号:【{wcsTaskMain.Task_Code}】");

                                //调用WMS接口上报任务完成
                                var result = HttpRequest.httpRequest.WebPostRequest(JsonConvert.SerializeObject(obj), _TaskComplete);
                                if (result.errCode != "Err")
                                {
                                    RunLog.runLog.Warning($"{_modular}上报WMS任务完成失败 任务号:【{wcsTaskMain.Task_Code}】托盘号:【{wcsTaskMain.TrayBar_Code}】失败信息【{result.errMsg}】");
                                    continue;
                                }
                                RunLog.runLog.Debug($"{_modular}上报WMS任务完成成功 任务号:【{wcsTaskMain.Task_Code}】");
                            }
                            else
                            {
                                RunLog.runLog.Debug($"{_modular}任务号:【{wcsTaskMain.Task_Code}】WCS自建任务，无需上报WMS");
                            }
                            //更新任务状态 更新主任务提示
                            _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                                .SetColumns(w => new WcsTaskMain()
                                {
                                    TaskTips = "任务完成",
                                    Task_State = (int)Task_State.任务完成,
                                    CompleteTime = DateTime.Now,
                                })
                                .Where(w => w.Task_Code == wcsTaskMain.Task_Code)
                                .ExecuteCommand();
                        }
                        if (wcsTaskMain.Task_State == (int)Task_State.任务完成)
                        {
                            RunLog.runLog.Debug($"{_modular}任务完成,删除任务，任务号:【{wcsTaskMain.Task_Code}】");

                            DeleteMainTask(wcsTaskMain.Id, "任务完成");
                        }
                    }
                }
                catch (Exception ex)
                {
                    RunLog.runLog.Error($@"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
                }
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 拆分主任务
        /// </summary>
        /// <param name="wcsTaskMain"></param>
        public bool SplitTaskMain(WcsTaskMain wcsTaskMain)
        {
            while (true)
            {
                try
                {
                    WcsRoute NextRoute = new WcsRoute();

                    if (!wcsTaskMain.TaskTips.Contains($"准备拆分主任务【{wcsTaskMain.Task_Code}】条码:【{wcsTaskMain.TrayBar_Code}】"))
                    {
                        //更新任务提示
                        _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                             .SetColumns(w => w.TaskTips == w.TaskTips + $"准备拆分主任务【{wcsTaskMain.Task_Code}】条码:【{wcsTaskMain.TrayBar_Code}】")
                             .Where(w => w.Task_Code == wcsTaskMain.Task_Code).ExecuteCommand();

                        RunLog.runLog.Debug($"{_modular}准备拆分主任务【{wcsTaskMain.Task_Code}】条码:【{wcsTaskMain.TrayBar_Code}】");
                    }

                    //不等于移库
                    if (wcsTaskMain.Task_Type != "move")
                    {
                        //意向下一个目标站台
                        List<string> intentionStation = new List<string>();
                        if (!wcsTaskMain.intentionStation.IsNullOrEmpty())
                        {
                            intentionStation.Add(wcsTaskMain.intentionStation);
                        }
                        //if (wcsTaskMain.Current_Station == "1001")
                        //{
                        //    //首先找到当前站台的下一段路径集合
                        //    var nextList = RouteSet.routeSet._wcsRoute.FindAll(r => r.Start_Station == wcsTaskMain.Current_Station);//.Select(r => r.Next_Station).ToList();

                        //    //站到被占用的站台集合
                        //    formulateStation = nextList.FindAll(n => ConveyorTask._conveyorTask.wcsTaskConveyorList.Find(c => c.End_Station == n.Next_Station) != null).Select(n => n.Next_Station).ToList();
                        //}

                        //根据当前位置和目标位置拆分路径
                        NextRoute = RouteSet.routeSet.RouteQuery(wcsTaskMain.Current_Station, wcsTaskMain.End_Station, intentionStation);
                        RouteSet.routeSet._targetStation = null;
                        RouteSet.routeSet.routerRmember.Clear();
                        intentionStation.Clear();
                        if (NextRoute == null)
                        {
                            //更新主任务的任务提示
                            _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                                .SetColumns(w => w.TaskTips == $"起始位置【{wcsTaskMain.Current_Station}】 到 目标位置【{wcsTaskMain.End_Station}】路径不通 无法拆分任务")
                                .Where(w => w.Task_Code == wcsTaskMain.Task_Code).ExecuteCommand();

                            //路径不通请检查路径配置
                            RunLog.runLog.Warning($"{_modular}起始位置【{wcsTaskMain.Current_Station}】 到 目标位置【{wcsTaskMain.End_Station}】路径不通 无法拆分任务");

                            return false;
                        }

                        if (!wcsTaskMain.TaskTips.Contains($"准备拆分主任务【{wcsTaskMain.Task_Code}】条码:【{wcsTaskMain.TrayBar_Code}】"))
                        {
                            //更新任务提示
                            _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                                 .SetColumns(w => w.TaskTips == w.TaskTips + $"任务号:【{wcsTaskMain.Task_Code}】拆分出下一步指令 起始位置【{NextRoute.Start_Station}】 到 目标位置【{NextRoute.Next_Station}】")
                                 .Where(w => w.Task_Code == wcsTaskMain.Task_Code).ExecuteCommand();

                            RunLog.runLog.Debug($"{_modular}任务号:【{wcsTaskMain.Task_Code}】拆分出下一步指令 起始位置【{NextRoute.Start_Station}】 到 目标位置【{NextRoute.Next_Station}】");
                        }

                        //if (ConnectPlc.connectPlc.GetStationNo(NextRoute.Next_Station) == null ||
                        //ConnectPlc.connectPlc.GetStationNo(NextRoute.Start_Station) == null)
                        //{
                        //    //更新主任务的任务提示
                        //    TaskDapper.Instance.UpdateMainTaskTips(wcsTaskMain.Task_Code, $"起始位置【{NextRoute.Start_Station}】 或者 目标位置【{NextRoute.Next_Station}】的站台为空 无法拆分任务", ref sqllist);

                        //    ShouLog.shouLog.Debug($"起始位置【{NextRoute.Start_Station}】 或者 目标位置【{NextRoute.Next_Station}】的站台为空 无法拆分任务");
                        //    return;
                        //}
                    }

                    bool success = true;

                    //判断该路径是有那个设备来执行
                    if (NextRoute.Dev_Type == Dev_Type.Convey.ToString())//输送线
                    {
                        RunLog.runLog.Debug($"{_modular}任务号:【{wcsTaskMain.Task_Code}】开始创建输送线任务");
                        success = ConveyorTask._conveyorTask.MainTaskSplitConveyTask(wcsTaskMain, NextRoute);
                    }
                    if (NextRoute.Dev_Type == Dev_Type.Stacker.ToString() || wcsTaskMain.Task_Type == "move")//堆垛机或者移库类型
                    {
                        RunLog.runLog.Debug($"{_modular}任务号:【{wcsTaskMain.Task_Code}】开始创建堆垛机任务");
                        success = StackerTask._stackerTask.MainTaskSplitStackerTask(wcsTaskMain, NextRoute);
                    }
                    if (NextRoute.Dev_Type == Dev_Type.AGV.ToString())//AGV
                    {

                        if (!wcsTaskMain.TaskTips.Contains($"【{wcsTaskMain.Task_Code}】开始创建AGV任务"))
                        {
                            //更新任务提示
                            _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                                 .SetColumns(w => w.TaskTips == w.TaskTips + $"【{wcsTaskMain.Task_Code}】开始创建AGV任务")
                                 .Where(w => w.Task_Code == wcsTaskMain.Task_Code).ExecuteCommand();

                            RunLog.runLog.Debug($"{_modular}任务号:【{wcsTaskMain.Task_Code}】开始创建AGV任务");
                        }
                        var firstAGVTask = _SqlSugarDapper.DB.Queryable<WcsTaskMain>()
                            .Where(w => w.Split == 1 && w.Start_Station == wcsTaskMain.Start_Station).OrderBy(w => w.CreateTime, OrderByType.Asc)
                            .ToList().First();

                        if (firstAGVTask.Task_Code == wcsTaskMain.Task_Code)
                        {
                            success = AGVTask._agvTask.MainTaskSplitAGVTask(wcsTaskMain, NextRoute);
                        }
                        else
                        {
                            return false;
                        }
                    }
                    if (!success)
                    {
                        if (!wcsTaskMain.TaskTips.Contains($"准备拆分主任务【{wcsTaskMain.Task_Code}】条码:【{wcsTaskMain.TrayBar_Code}】"))
                        {
                            //更新任务提示
                            _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                                 .SetColumns(w => w.TaskTips == w.TaskTips + $"主任务拆分失败，任务号:【{wcsTaskMain.Task_Code}】")
                                 .Where(w => w.Task_Code == wcsTaskMain.Task_Code).ExecuteCommand();

                            RunLog.runLog.Warning($"{_modular}主任务拆分失败，任务号:【{wcsTaskMain.Task_Code}】");
                        }
                        return false;
                    }

                    //更新主任务为不可拆分状态 更新任务状态
                    _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                          .SetColumns(w => new WcsTaskMain()
                          {
                              Task_State = (int)Task_State.等待执行,
                              TaskTips = "拆分成功，等待反馈成功",
                              Split = 0
                          })
                          .Where(w => w.Task_Code == wcsTaskMain.Task_Code).ExecuteCommand();

                    return true;
                }
                catch (Exception ex)
                {
                    RunLog.runLog.Error($@"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
                    return false;
                }
            }
        }

        /// <summary>
        /// 获取站台生产物料
        /// </summary>
        /// <returns></returns>
        public string GetStationMaterial(string station)
        {
            return _SqlSugarDapper.DB.Queryable<WcsDevStation>().Where(w => w.Station_Plc_No == station).First().ProductionMaterials;
        }

        /// <summary>
        /// 生成子任务号
        /// </summary>
        /// <returns></returns>
        public static string GenerateRandomCode(string main)
        {

            if (main == "main")
            {
                var mainCode = _SqlSugarDapper.DB.Queryable<SystemData>().Where(w => w.sysName == "MainTaskCode").First();

                var d = _SqlSugarDapper.DB.Updateable<SystemData>()
                    .Where(w => w.sysName == "MainTaskCode");

                if (mainCode.sysValue >= 50000)
                {
                    d.SetColumns(s => s.sysValue == 1);
                }
                else
                {
                    d.SetColumns(s => s.sysValue == s.sysValue + 1);
                }
                d.ExecuteCommand();

                return DateTime.Now.ToString("yyyyMMddssffffff") + mainCode.sysValue.ToString().PadLeft(5, '0');
            }
            else if (main == "main1")
            {
                var r = new Random(Guid.NewGuid().GetHashCode());
                var result = new StringBuilder();

                for (var i = 0; i < 10; i++)
                {
                    result.Append(r.Next(0, 9));
                }
                return DateTime.Now.ToString("yyyyMMdd") + result.ToString();
            }
            else
            {
                //string subTaskCode = DateTime.Now.ToString("yyyyMMddHHmmss") + r.Next(0, 10) + r.Next(0, 10);
                lock (_lock)
                {
                    var sub = _SqlSugarDapper.DB.Queryable<SystemData>().Where(w => w.sysName == "SubTaskCode").First();

                    var d = _SqlSugarDapper.DB.Updateable<SystemData>()
                        .Where(w => w.sysName == "SubTaskCode");

                    if (sub.sysValue >= 30000)
                    {
                        d.SetColumns(s => s.sysValue == 1);
                    }
                    else
                    {
                        d.SetColumns(s => s.sysValue == s.sysValue + 1);
                    }
                    d.ExecuteCommand();

                    return sub.sysValue.ToString();
                }
            }
        }

        /// <summary>
        /// 读取设备条码--线程
        /// </summary>
        private void ReadTrayCode()
        {
            while (true)
            {
                try
                {
                    var trayCode = _SqlSugarDapper.DB.Queryable<WcsReadTrayCode>().ToList();
                    foreach (var barCode in trayCode.FindAll(w => w.TrayBar_Code != null && w.TrayBar_Code != ""))
                    {
                        if (TrayBarCode(barCode))
                        {
                            _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                .SetColumns(w => w.TrayBar_Code == "")
                                .Where(w => w.Station_Plc_No == barCode.Station_Plc_No)
                                .ExecuteCommand();
                        }
                    }

                    CallMaterial();

                    //foreach (var item in SandCoreStation)
                    //{
                    //    //if (item != "1001")
                    //    //{
                    //    //    continue;
                    //    //}
                    //    var lo = _SqlSugarDapper.DB.Queryable<LocationInfo>().Where(w => w.StationLocation == item && (w.state == (int)StationState.在库 || w.state == (int)StationState.入库占用)).First();

                    //    if (lo == null)
                    //    {
                    //        string station = (Convert.ToInt32(item) + 4).ToString();

                    //        //根据站台信息获取托盘号
                    //        var locationInfo = LocationInfo.GetStationInfo(station);
                    //        if (locationInfo != null && locationInfo.state == (int)StationState.在库)
                    //        {
                    //            WcsTaskMain wcsTaskMain1 = new WcsTaskMain
                    //            {
                    //                TrayBar_Code = locationInfo.BarCode1 + "," + locationInfo.BarCode2,
                    //                Start_Station = station,
                    //                End_Station = item,
                    //                MaterialType = locationInfo.MaterialInfo,
                    //                ContinueProduction = 1,
                    //                Current_Station = station,
                    //                ProcessType = ProcessType.砂芯缓存到制砂芯.ToString(),
                    //            };
                    //            _SqlSugarDapper.DB.Insertable(wcsTaskMain1).ExecuteCommand();
                    //        }
                    //    }
                    //}
                }
                catch (Exception ex)
                {
                    RunLog.runLog.Error($@"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
                }
                Thread.Sleep(2000);
            }
        }

        /// <summary>
        /// PDA扫码呼叫送料
        /// </summary>
        public void CallMaterial()
        {
            try
            {
                foreach (var callMaterial in _SqlSugarDapper.DB.Queryable<CallMaterial>().ToList().FindAll(f => !f.CallStation.IsNullOrEmpty()))
                {
                    if (callMaterial.CallStation.Length != 4)
                    {
                        _SqlSugarDapper.DB.Deleteable<CallMaterial>().Where(w => w.CallStation == callMaterial.CallStation).ExecuteCommand();
                        return;
                    }
                    //判断呼叫站台是砂芯还是铸造
                    if (castingStations.Find(f => f.Contains(callMaterial.CallStation)) != null)
                    {
                        //判断当前物料类型的出库任务是否大于6个
                        var task = _SqlSugarDapper.DB.Queryable<WcsTaskMain>().Where(w => w.MaterialType == "X03后副车架砂芯" && w.Task_Type == "out" && w.brother != null && (w.Current_Station == "9001" || w.Current_Station == "9002")).ToList();
                        if (task.Count() >= 12)
                        {
                            //RunLog.runLog.Debug($@"{_modular} 【{callMaterial.MaterialType}】已有任务暂不下发");
                            //暂不拆分
                            continue;
                        }
                        var taskNPC = _SqlSugarDapper.DB.Queryable<WcsTaskMain>().Where(w => w.MaterialType == "NPC后副车架砂芯" && w.Task_Type == "out" && w.brother != null && (w.Current_Station == "9001" || w.Current_Station == "9002")).ToList();
                        if (taskNPC.Count() >= 8)
                        {
                            //RunLog.runLog.Debug($@"{_modular} 【{callMaterial.MaterialType}】已有任务暂不下发");
                            //暂不拆分
                            continue;
                        }
                        var taskXC40 = _SqlSugarDapper.DB.Queryable<WcsTaskMain>().Where(w => w.MaterialType == "XC40后副车架砂芯" && w.Task_Type == "out" && w.brother != null && (w.Current_Station == "9001" || w.Current_Station == "9002")).ToList();
                        if (taskXC40.Count() >= 8)
                        {
                            //RunLog.runLog.Debug($@"{_modular} 【{callMaterial.MaterialType}】已有任务暂不下发");
                            //暂不拆分
                            continue;
                        }

                        var count = _SqlSugarDapper.DB.Queryable<LocationInfo>()
                            .Where(w => w.StationLocation.Contains("40") && w.MaterialInfo == callMaterial.MaterialType)
                            .ToList().Count();

                        var areaCount = _SqlSugarDapper.DB.Queryable<AreaLocation>()
                            .Where(w => w.MaterialType == callMaterial.MaterialType && w.AreaCode == "4000" && w.Enable == "1" && w.BinCode == 1)
                            .ToList().Count();

                        if (count >= areaCount)
                        {
                            _SqlSugarDapper.DB.Deleteable<LocationInfo>()
                                .Where(w => w.StationLocation.Contains("40") && w.MaterialInfo == callMaterial.MaterialType)
                                .ExecuteCommand();
                        }

                        //叫料任务开启关闭
                        var type = _SqlSugarDapper.DB.Queryable<WcsDevPlc>().Where(w => w.PLC_Name.Contains("托盘库堆垛机"))
                        .First().Plc_Type;

                        if (type == "1")
                        {
                            RunLog.runLog.Debug($@"{_modular}已关闭叫料任务");
                        }
                        else
                        {
                            //铸造叫料
                            CastingStationsCall(callMaterial);
                        }
                    }
                    else if (qualityTestingStation.Find(f => f.Contains(callMaterial.CallStation)) != null)
                    {
                        //质检
                        QualityTestingReturn(callMaterial.CallStation);
                    }
                    else if (SandCoreStation.Find(f => f.Contains(callMaterial.CallStation)) != null)
                    {
                        //var loc = _SqlSugarDapper.DB.Queryable<LocationInfo>()
                        //    .Where(w => w.StationLocation == (Convert.ToInt32(callMaterial.CallStation) + 4).ToString())
                        //    .First();

                        //if (loc != null && loc.state != (int)StationState.在库)
                        //{
                        //    var strMaterial = _SqlSugarDapper.DB.Queryable<WcsDevStation>()
                        //     .Where(w => w.Station_Plc_No == (Convert.ToInt32(callMaterial.CallStation) + 4).ToString()).First();

                        //    _SqlSugarDapper.DB.Updateable<LocationInfo>()
                        //        .SetColumns(w=>w.state==(int)StationState.在库)
                        //        .Where(w => w.StationLocation == (Convert.ToInt32(callMaterial.CallStation) + 4).ToString())
                        //        .ExecuteCommand();
                        //}
                        //else
                        //{
                        //    var strMaterial = _SqlSugarDapper.DB.Queryable<WcsDevStation>()
                        //    .Where(w => w.Station_Plc_No == (Convert.ToInt32(callMaterial.CallStation) + 4).ToString()).First();

                        //    _SqlSugarDapper.DB.Insertable(new LocationInfo
                        //    {
                        //        MaterialInfo = strMaterial.ProductionMaterials,
                        //        StationLocation = strMaterial.Station_Plc_No,
                        //        state = (int)StationState.在库
                        //    }).ExecuteCommand();
                        //}

                        //砂芯叫料
                        SandCoreOffline(callMaterial);
                    }
                    else if (SandCoreBufferStation.Find(f => f.Contains(callMaterial.CallStation)) != null)
                    {
                        CacheReplenishmentCall(callMaterial.CallStation);
                    }

                    Thread.Sleep(500);
                }
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($@"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
            }

        }

        /// <summary>
        /// 砂芯下线
        /// </summary>
        public void SandCoreOffline(CallMaterial callMaterial)
        {
            var sta = _SqlSugarDapper.DB.Queryable<SystemData>()
                 .Where(w => w.sysName == "Station")
                 .First();

            WcsTaskMain wcsTaskMain = new WcsTaskMain()
            {
                Task_Type = "in",
                MaterialType = GetStationMaterial(callMaterial.CallStation),// 物料号
                Start_Station = callMaterial.CallStation,// 站台号
                End_Station = sta.sysValue == 1 ? "A001" : "A007",
                ProcessType = ProcessType.砂芯下线到入库口到缓存区.ToString(),
                Current_Station = callMaterial.CallStation,
            };
            WcsTaskMain wcsTaskMain1 = null;
            if (callMaterial.isSupply == 1)
            {
                string station = (Convert.ToInt32(callMaterial.CallStation) + 4).ToString();

                var strMaterial = _SqlSugarDapper.DB.Queryable<WcsDevStation>()
                     .Where(w => w.Station_Plc_No == station).First();
                //根据站台信息获取托盘号
                var locationInfo = LocationInfo.GetStationInfo(station);
                wcsTaskMain1 = new WcsTaskMain
                {
                    TrayBar_Code = "",
                    Start_Station = station,
                    End_Station = callMaterial.CallStation,
                    MaterialType = strMaterial.ProductionMaterials,
                    ContinueProduction = 1,
                    Current_Station = station,
                    ProcessType = ProcessType.砂芯缓存到制砂芯.ToString(),
                };
            }
            if (sta.sysValue == 1)
            {
                _SqlSugarDapper.DB.Updateable<SystemData>()
                .SetColumns(w => w.sysValue == 2)
                 .Where(w => w.sysName == "Station")
                 .ExecuteCommand();
            }
            else if (sta.sysValue == 2)
            {
                _SqlSugarDapper.DB.Updateable<SystemData>()
                .SetColumns(w => w.sysValue == 1)
                 .Where(w => w.sysName == "Station")
                 .ExecuteCommand();
            }

            _SqlSugarDapper.DB.Insertable(wcsTaskMain).ExecuteCommand();
            _SqlSugarDapper.DB.Ado.ExecuteCommand($"DELETE top(1) WCS_CallMaterial where CallStation = '{callMaterial.CallStation}'");
            _SqlSugarDapper.DB.Insertable(wcsTaskMain1).ExecuteCommand();
        }

        /// <summary>
        /// 铸造下线叫料
        /// </summary>
        public void CastingStationsCall(CallMaterial callMaterial)
        {
            try
            {
                bool createAgvTask = true;
                RunLog.runLog.Debug($@"{_modular}  准备处理铸造叫料 【{callMaterial.CallStation}】 呼叫数量【{callMaterial.SupplyNum}】");
                callMaterial.SupplyNum = 2;

                //不补料，删除叫料任务
                if (callMaterial.isSupply == 1)
                {
                    //判断呼叫站台是否在位
                    //var callStation = LocationInfo.GetStationInfo(callMaterial.CallStation);
                    //找可用空站台0
                    var freeStation = LocationInfo.GetCacheBit("4000", 1, callMaterial.MaterialType);

                    if (freeStation == null)
                    {
                        RunLog.runLog.Warning($"{_modular}空托缓存 没有可用库位");
                        return;
                    }
                    var station = Convert.ToInt32(callMaterial.CallStation) + 10;

                    WcsTaskMain wcsTaskMain = null;
                    wcsTaskMain = new WcsTaskMain
                    {
                        Task_Type = "in",
                        Start_Station = station.ToString(),
                        End_Station = "4000",
                        Current_Station = station.ToString(),
                        StartWMSBinCode = "8",
                        MaterialType = callMaterial.MaterialType,
                        Replenishment = freeStation,
                        ProcessType = ProcessType.铸造到缓存区.ToString(),
                    };
                    _SqlSugarDapper.DB.Insertable(wcsTaskMain).ExecuteCommand();
                    //LocationInfo.ChangeStatioState(callMaterial.CallStation, StationState.出库占用);
                    _SqlSugarDapper.DB.Deleteable<CallMaterial>().Where(w => w.CallStation == callMaterial.CallStation).ExecuteCommand();
                    return;
                }

                //根据物料信息找到可用库存站台  空小车 （为“空”&&在库55）
                var availableStation = LocationInfo.GetAvailableStation(MaterialType.空.ToString(), 0);

                availableStation = "4009";
                WcsTaskMain wcsTaskMain1 = null;

                //没有空料车
                if (availableStation == null)
                {
                    //要在空托缓存找一个料车入库
                    var locationInfo = LocationInfo.GetAvailableStation();
                    if (locationInfo == null)
                    {
                        return;
                    }
                    availableStation = locationInfo.StationLocation;

                    LocationInfo.ChangeStatioState(locationInfo.StationLocation, StationState.出库占用);

                    //入库
                    wcsTaskMain1 = new WcsTaskMain
                    {
                        Task_Type = "in",
                        TrayBar_Code = locationInfo.BarCode1 + "," + locationInfo.BarCode2,
                        Start_Station = locationInfo.StationLocation,
                        End_Station = AGVTask._agvTask.GetStoragePortTask("in"),//那个入库口任务少就去那个
                        Current_Station = "4000",
                        Replenishment = locationInfo.StationLocation,
                        MaterialType = callMaterial.MaterialType,
                        ProcessType = ProcessType.缓存区到入库口到缓存区.ToString(),
                    };
                    createAgvTask = false;
                }
                else
                {
                    LocationInfo.ChangeStatioState(availableStation, StationState.预占用);
                }

                //var flag = _SqlSugarDapper.DB.Queryable<WcsDevPlc>().Where(w => w.PLC_Name.Contains("托盘库堆垛机"))
                //    .First().Dev_Type;

                var flag = _SqlSugarDapper.DB.Queryable<PalletToMaterial>().Where(w => w.MaterialType == callMaterial.MaterialType)
                    .First().Flag;

                List<WarehouseInfo> location;

                if (flag == "false")
                {
                    //从库存配置表里找到所在层
                    location = Warehouse.GetWarehouseByMaterialTypeOut11(1, callMaterial.MaterialType, "9001");
                    _SqlSugarDapper.DB.Updateable<PalletToMaterial>()
                              .SetColumns(w => w.Flag == "true")
                              .Where(w => w.MaterialType == callMaterial.MaterialType)
                              .ExecuteCommand();
                }
                else
                {
                    //从库存配置表里找到所在层
                    location = Warehouse.GetWarehouseByMaterialTypeOut11(1, callMaterial.MaterialType, "9002");
                    _SqlSugarDapper.DB.Updateable<PalletToMaterial>()
                             .SetColumns(w => w.Flag == "false")
                             .Where(w => w.MaterialType == callMaterial.MaterialType)
                             .ExecuteCommand();
                }

                if (location == null)
                {
                    LocationInfo.ChangeStatioState(availableStation, StationState.在库);
                    RunLog.runLog.Warning($@"{_modular} 【{callMaterial.MaterialType}】库内无货");

                    return;
                }
                //string ID = $"{location.WarehouseCode}-{location.layer}";

                //从库存信息表里找第一个物料
                //var info1 = WarehouseInfo.GetWarehouseInfoById(location[0]);
                RunLog.runLog.Warning($@"{_modular} 第一个出库托盘【{location[0].ID}】托盘号【{location[0].barCode}】");

                WarehouseInfo.ChangeWarehouseInfo(location[0], (int)StationState.出库占用);

                //出库库存
                WarehouseIO.AddWarehouseInfo(new WarehouseIO
                {
                    ID = location[0].barCode.Substring(6, 8),
                    barCode = location[0].barCode,
                    CreateTime = DateTime.Now,
                    Task_type = "out",
                    BarCodeData = callMaterial.MaterialType,
                    WarehouseCode = location[0].ID
                });
                //如果只叫一个物料
                if (callMaterial.SupplyNum == 2)
                {
                    WarehouseInfo.ChangeWarehouseInfo(location[1], (int)StationState.出库占用);

                    //出库库存
                    WarehouseIO.AddWarehouseInfo(new WarehouseIO
                    {
                        ID = location[1].barCode.Substring(6, 8),
                        barCode = location[1].barCode,
                        CreateTime = DateTime.Now,
                        Task_type = "out",
                        BarCodeData = callMaterial.MaterialType,
                        WarehouseCode = location[0].ID

                    });
                    RunLog.runLog.Warning($@"{_modular} 第二个出库托盘【{location[1].ID}】托盘号【{location[1].barCode}】");
                }

                var End_Station = createAgvTask ? AGVTask._agvTask.GetStoragePortTask("out") : callMaterial.CallStation;

                //判断C区D区是否都有任务
                //if (OutTask()) 
                //{
                //    if (location[0].ID.Contains("9001"))
                //    {
                //        End_Station = "B001";
                //    }
                //    else
                //    {
                //        End_Station = "B007";
                //    }
                //}

                if (location[0].ID.Contains("9001"))
                {
                    End_Station = "B001";
                }
                else
                {
                    End_Station = "B007";
                }

                WcsTaskMain wcsTaskMain2 = new WcsTaskMain
                {
                    Task_Type = "out",
                    TrayBar_Code = location[0].barCode,
                    Start_Station = location[0].ID.Substring(0, 4),
                    End_Station = End_Station,
                    Current_Station = location[0].ID.Substring(0, 4),
                    StartWMSBinCode = location[0].ID.Substring(5),
                    Replenishment = availableStation,
                    intentionStation = End_Station,
                    MaterialType = callMaterial.MaterialType,
                    ProcessType = ProcessType.缓存区到出库口到铸造.ToString(),
                };
                WcsTaskMain wcsTaskMain3 = null;
                if (callMaterial.SupplyNum == 2)
                {
                    wcsTaskMain3 = new WcsTaskMain
                    {
                        Task_Type = "out",
                        TrayBar_Code = location[1].barCode,
                        Start_Station = location[1].ID.Substring(0, 4),
                        End_Station = wcsTaskMain2.End_Station,
                        Current_Station = location[1].ID.Substring(0, 4),
                        StartWMSBinCode = location[1].ID.Substring(5),
                        Replenishment = availableStation,
                        intentionStation = wcsTaskMain2.intentionStation,
                        MaterialType = callMaterial.MaterialType,
                        ProcessType = ProcessType.缓存区到出库口到铸造.ToString(),
                    };
                }
                WcsTaskMain wcsTaskMain4 = new WcsTaskMain();
                if (createAgvTask)
                {
                    //agv任务
                    wcsTaskMain4 = new WcsTaskMain
                    {
                        Task_Type = "out",
                        TrayBar_Code = location[0].barCode + "," + location[1].barCode,
                        Start_Station = wcsTaskMain2.intentionStation,
                        End_Station = callMaterial.CallStation,
                        Current_Station = wcsTaskMain2.intentionStation,
                        StartWMSBinCode = "",
                        Replenishment = wcsTaskMain2.intentionStation == "B001" ? "4009" : "4008",
                        //Replenishment = availableStation,
                        MaterialType = callMaterial.MaterialType,
                        ProcessType = ProcessType.缓存区到出库口到铸造.ToString(),
                    };
                }
                _SqlSugarDapper.DB.BeginTran();

                try
                {
                    if (callMaterial.SupplyNum == 2)
                    {
                        //关联任务号
                        wcsTaskMain2.brother = wcsTaskMain3.Task_Code;
                        wcsTaskMain3.brother = wcsTaskMain2.Task_Code;
                        _SqlSugarDapper.DB.Insertable(wcsTaskMain3).ExecuteCommand();
                    }

                    _SqlSugarDapper.DB.Ado.ExecuteCommand($"DELETE top(1) WCS_CallMaterial where CallStation = '{callMaterial.CallStation}' and MaterialType = '{callMaterial.MaterialType}'");
                    _SqlSugarDapper.DB.Insertable(wcsTaskMain1).ExecuteCommand();
                    _SqlSugarDapper.DB.Insertable(wcsTaskMain2).ExecuteCommand();
                    if (createAgvTask)
                    {
                        _SqlSugarDapper.DB.Insertable(wcsTaskMain4).ExecuteCommand();
                    }
                    _SqlSugarDapper.DB.CommitTran();
                }
                catch (Exception ex)
                {
                    RunLog.runLog.Error($@"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
                    _SqlSugarDapper.DB.RollbackTran();
                }
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($@"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
            }
        }

        /// <summary>
        /// 质检站台回库
        /// </summary>
        public void QualityTestingReturn(string callStation)
        {
            try
            {
                var codeInfo = LocationInfo.GetStationInfo(callStation);
                //入库
                WcsTaskMain wcsTaskMain1 = new WcsTaskMain
                {
                    Task_Type = "in",
                    TrayBar_Code = codeInfo?.BarCode1 + "," + codeInfo?.BarCode2,
                    Start_Station = callStation,
                    End_Station = AGVTask._agvTask.GetStoragePortTask("in"),//那个入库口任务少就去那个
                    Current_Station = callStation,
                    ProcessType = ProcessType.质检到入库口到缓存区.ToString(),
                };
                _SqlSugarDapper.DB.Insertable(wcsTaskMain1).ExecuteCommand();
                _SqlSugarDapper.DB.Ado.ExecuteCommand($"DELETE top(1) WCS_CallMaterial where CallStation = '{callStation}'");
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($@"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
            }
        }

        /// <summary>
        /// 砂芯缓存站台补料车
        /// </summary>
        public void CacheReplenishmentCall(string callStation)
        {
            try
            {
                var materialType = GetStationMaterial(callStation);

                //托盘类型      找到空托盘站台
                //var availableStation = LocationInfo.GetAvailableStation(materialType, 1);
                var availableStation = GetInStation(materialType);
                //availableStation = "4006";
                //判断是否有可用料车
                if (availableStation == null)
                {
                    //要在空托缓存入库一个托盘的站台上
                    var locationInfo = LocationInfo.GetAvailableStation();
                    if (locationInfo == null)
                    {
                        return;
                    }
                    availableStation = locationInfo.StationLocation;

                    LocationInfo.ChangeStatioState(locationInfo.StationLocation, StationState.预占用);

                    WcsTaskMain wcsTaskMain1 = null;
                    //当前托盘是哪个类型
                    //入库
                    if (locationInfo.MaterialInfo != MaterialType.空.ToString())
                    {
                        wcsTaskMain1 = new WcsTaskMain
                        {
                            Task_Type = "in",
                            TrayBar_Code = locationInfo.BarCode1 + "," + locationInfo.BarCode2,
                            Start_Station = locationInfo.StationLocation,
                            End_Station = AGVTask._agvTask.GetStoragePortTask("in"),//那个入库口任务少就去那个
                            Current_Station = "4000",
                            Replenishment = locationInfo.StationLocation,
                            MaterialType = materialType,
                            ProcessType = ProcessType.缓存区到入库口到缓存区.ToString(),
                        };
                        LocationInfo.ChangeStatioState(locationInfo.StationLocation, StationState.出库占用);
                    }

                    //根据物料号查询这个物料在那个仓库的第几层
                    var inWarehouse = Warehouse.GetWarehouseByMaterialTypeOut11(0, materialType, "9002");

                    if (inWarehouse == null)
                    {
                        LocationInfo.ChangeStatioState(locationInfo.StationLocation, StationState.在库);
                        RunLog.runLog.Warning($@"{_modular} 【{materialType}】库内无货");

                        return;
                    }

                    WarehouseInfo.ChangeWarehouseInfo(inWarehouse[0], (int)StationState.出库占用);
                    WarehouseInfo.ChangeWarehouseInfo(inWarehouse[1], (int)StationState.出库占用);

                    //出库
                    WcsTaskMain wcsTaskMain2 = new WcsTaskMain
                    {
                        Task_Type = "out",
                        TrayBar_Code = inWarehouse[0].barCode,
                        Start_Station = inWarehouse[0].ID.Substring(0, 4),
                        End_Station = AGVTask._agvTask.GetStoragePortTask("out", 1),
                        //End_Station = callStation,
                        Current_Station = inWarehouse[0].ID.Substring(0, 4),
                        StartWMSBinCode = inWarehouse[0].ID.Substring(5),
                        Replenishment = locationInfo.StationLocation,
                        intentionStation = AGVTask._agvTask.GetStoragePortTask("out", 1),
                        MaterialType = materialType,
                        ProcessType = ProcessType.出库口到砂芯缓存区.ToString(),
                    };

                    //出库
                    WcsTaskMain wcsTaskMain3 = new WcsTaskMain
                    {
                        Task_Type = "out",
                        TrayBar_Code = inWarehouse[1].barCode,
                        Start_Station = inWarehouse[1].ID.Substring(0, 4),
                        End_Station = wcsTaskMain2.intentionStation,
                        //End_Station = callStation,
                        Current_Station = inWarehouse[1].ID.Substring(0, 4),
                        StartWMSBinCode = inWarehouse[1].ID.Substring(5),
                        Replenishment = locationInfo.StationLocation,
                        intentionStation = wcsTaskMain2.intentionStation,
                        MaterialType = materialType,
                        ProcessType = ProcessType.出库口到砂芯缓存区.ToString(),
                    };

                    //agv任务
                    WcsTaskMain wcsTaskMain4 = new WcsTaskMain
                    {
                        Task_Type = "out",
                        TrayBar_Code = inWarehouse[0].barCode + "," + inWarehouse[1].barCode,
                        Start_Station = wcsTaskMain2.intentionStation,
                        End_Station = callStation,
                        Current_Station = "4000",
                        MaterialType = materialType,
                        Replenishment = availableStation,
                        ProcessType = ProcessType.出库口到砂芯缓存区.ToString(),
                    };

                    //关联任务号
                    wcsTaskMain2.brother = wcsTaskMain3.Task_Code;
                    wcsTaskMain3.brother = wcsTaskMain2.Task_Code;

                    _SqlSugarDapper.DB.BeginTran();

                    _SqlSugarDapper.DB.Insertable(wcsTaskMain1).ExecuteCommand();
                    _SqlSugarDapper.DB.Insertable(wcsTaskMain2).ExecuteCommand();
                    _SqlSugarDapper.DB.Insertable(wcsTaskMain3).ExecuteCommand();
                    _SqlSugarDapper.DB.Insertable(wcsTaskMain4).ExecuteCommand();

                    _SqlSugarDapper.DB.Ado.ExecuteCommand($"DELETE top(1) WCS_CallMaterial where CallStation = '{callStation}'");
                    _SqlSugarDapper.DB.CommitTran();

                    return;
                }
                else
                {
                    LocationInfo.ChangeStatioState(availableStation, StationState.预占用);
                }
                //var codeInfo = LocationInfo.GetStationInfo(availableStation);

                //if (codeInfo != null)
                {
                    WcsTaskMain wcsTaskMain = new WcsTaskMain
                    {
                        Task_Type = "out",
                        TrayBar_Code = "",//codeInfo.BarCode1 + "," + codeInfo.BarCode2,
                        Start_Station = availableStation,
                        End_Station = callStation,
                        Current_Station = "4000",
                        MaterialType = materialType,
                        Replenishment = "4008",
                        //Replenishment = availableStation,
                        ProcessType = ProcessType.缓存区到制砂芯缓存区.ToString(),
                    };
                    _SqlSugarDapper.DB.Deleteable<CallMaterial>().Where(w => w.CallStation == callStation).ExecuteCommand();
                    _SqlSugarDapper.DB.Insertable(wcsTaskMain).ExecuteCommand();
                }
            }
            catch (Exception ex)
            {
                _SqlSugarDapper.DB.RollbackTran();
                RunLog.runLog.Error($@"{_modular}异常信息【{ex.Message}】【{ex.StackTrace}】");
            }
        }

        /// <summary>
        /// 判断C区D区是否都有任务
        /// </summary>
        /// <returns></returns>
        public bool OutTask()
        {
            var cList = _wcsTaskMains.FindAll(w => w.Start_Station.Contains("9001")).ToList();
            var dList = _wcsTaskMains.FindAll(w => w.Start_Station.Contains("9002")).ToList();

            if (cList.Count() != 0 && dList.Count() != 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="materialType"></param>
        /// <returns></returns>
        public string GetInStation(string materialType)
        {
            var station = _SqlSugarDapper.DB.Queryable<AreaLocation>()
                .Where(w => w.BinCode == 1 && w.Enable == "1" && w.MaterialType == materialType).ToList().First();
            return station.StationNo;
        }

        public string Byte_BitToString(byte[] val)
        {
            BitArray bitArray = new BitArray(val);
            string Text = "";

            for (int i = 0; i < bitArray.Count; i++)
            {
                Text += Convert.ToInt32(bitArray[i]);
            }

            return Text;
        }

        /// <summary>
        /// 处理扫到的条码
        /// </summary>
        /// <param name="barCode"></param>
        /// <returns>True清除条码，False不清除条码</returns>
        public bool TrayBarCode(WcsReadTrayCode readTrayCode)
        {
            try
            {
                //筛选掉条码等于空字符的数据
                if (readTrayCode.TrayBar_Code == "NOREAD")
                {
                    RunLog.runLog.Debug($"{_modular}站台【{readTrayCode.Station_Plc_No}】 条码为【{readTrayCode.TrayBar_Code}】不处理");
                    return true;
                }

                //自己处理
                if (readTrayCode.Station_Plc_No == "")
                {
                    RunLog.runLog.Debug($"{_modular}站台【{readTrayCode.Station_Plc_No}】 条码为【{readTrayCode.TrayBar_Code}】自己生成任务");
                    return true;
                }
                else
                {
                    //入库站台
                    if (readTrayCode.Station_Plc_No == "A002")
                    {
                        BarCodeInfo barCodeInfo = new BarCodeInfo()
                        {
                            BarCode = readTrayCode.TrayBar_Code
                        };

                        if (_LAY == "0")
                        {
                            _SqlSugarDapper.DB.Insertable(barCodeInfo).ExecuteCommand();
                        }

                        var barInfo = BarCodeInfo.GetBarCodeIsGood(readTrayCode.TrayBar_Code);

                        //截取托盘识别码
                        var IdentificationCode = readTrayCode.TrayBar_Code.Substring(6, 8);

                        var tishenji = readTrayCode.Station_Plc_No == "A002" ? 1 : 2;

                        //根据托盘吗判断是什么物料
                        var material = PalletToMaterial.GeMaterialTypeByPallet(IdentificationCode);

                        if (material == null)
                        {
                            _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】未找到托盘对应的物料类型")
                                .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();

                            RunLog.runLog.Warning($@"未找到托盘对应的物料类型 托盘码【{readTrayCode.TrayBar_Code}】");
                            return false;
                        }
                        //bool flag = false;
                        Warehouse warehouse;
                        if (barInfo == null)
                        {
                            //没有托盘信息就是空托盘
                            //根据物料号查询这个物料在那个仓库的第几层
                            warehouse = Warehouse.GetWarehouseByMaterialTypeIn(0, material.MaterialType, "9001");
                            BarCodeInfo.DeleteBarCodeInfo(readTrayCode.TrayBar_Code);
                        }
                        else
                        {
                            /*
                             * Dev_Code A002 标识
                             * Read_Block A006 标识
                             */
                            var flag1 = _SqlSugarDapper.DB.Queryable<WcsDevPlc>().Where(w => w.PLC_Name.Contains("托盘库堆垛机"))
                                        .First().Dev_Code;
                            if (flag1 == "false")
                            {
                                //根据物料号查询这个物料在那个仓库的第几层
                                warehouse = Warehouse.GetWarehouseByMaterialTypeIn(1, material.MaterialType, "9001");
                                BarCodeInfo.DeleteBarCodeInfo(readTrayCode.TrayBar_Code);
                                _SqlSugarDapper.DB.Updateable<WcsDevPlc>()
                                     .SetColumns(w => w.Dev_Code == "true")
                                     .Where(w => w.PLC_Name.Contains("托盘库堆垛机"))
                                     .ExecuteCommand();
                            }
                            else
                            {
                                //根据物料号查询这个物料在那个仓库的第几层
                                warehouse = Warehouse.GetWarehouseByMaterialTypeIn(1, material.MaterialType, "9002");
                                BarCodeInfo.DeleteBarCodeInfo(readTrayCode.TrayBar_Code);
                                _SqlSugarDapper.DB.Updateable<WcsDevPlc>()
                                     .SetColumns(w => w.Dev_Code == "false")
                                     .Where(w => w.PLC_Name.Contains("托盘库堆垛机"))
                                     .ExecuteCommand();
                            }
                        }

                        //找到一层如满料的并且没有物料的层
                        if (warehouse == null)
                        {
                            //var warehourseId = _SqlSugarDapper.DB.Queryable<Warehouse>()
                            //     .Where(w => w.IsFullMaterial == 1 && w.IsIN == 1 && w.IsOUT == 1 && SqlFunc.Subqueryable<WarehouseInfo>().Where(x => x.ID == w.ID).NotAny()).First();

                            //if (warehourseId == null)
                            //{
                            //    _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                            //    .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】没有库存")
                            //    .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();

                            //    RunLog.runLog.Warning($@"物料【{material.MaterialType}】没有库存 托盘码【{readTrayCode.TrayBar_Code}】");
                            //    return false;
                            //}

                            ////开辟新层
                            //_SqlSugarDapper.DB.Updateable<Warehouse>()
                            //    .SetColumns(w => w.MaterialType == material.MaterialType)
                            //    .SetColumns(w => w.IsIN == 1)
                            //    .SetColumns(w => w.IsOUT == 1)
                            //    .Where(w => w.ID == warehourseId.ID)
                            //    .ExecuteCommand();

                            //RunLog.runLog.Warning($@"物料【{material.MaterialType}】开辟新的库存【{warehourseId.ID}】");
                            //return false;

                            _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】没有库存")
                                .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();

                            RunLog.runLog.Warning($@"物料【{material.MaterialType}】没有库存 托盘码【{readTrayCode.TrayBar_Code}】");
                            return false;
                        }

                        string id = $"{warehouse.WarehouseCode}-{warehouse.layer}";

                        //满料
                        if (barInfo != null && (_ControlA006 == "1" && readTrayCode.Station_Plc_No == "A006" || _ControlA002 == "1" && readTrayCode.Station_Plc_No == "A002"))
                        {
                            var resultTrayStatus = HttpRequest.httpRequest.WebGetRequestMES(readTrayCode.TrayBar_Code, "http://10.3.15.130:8090/apis/Acc/ProductProcess/TrayStatus?trayCode=");
                            if (resultTrayStatus?.data.trayResultDesc == "制芯下料")
                            {
                                //调用接口告诉MES当前托盘入库成功
                                //入库上报MES
                                MESWriteData mESWriteData = new MESWriteData()
                                {
                                    MachineId = 129051,
                                    MachineType = 501,
                                    ActionTypeId = 1,
                                    data = new Data { TrayCode = readTrayCode.TrayBar_Code }
                                };
                                var result = HttpRequest.httpRequest.WebPostRequestMES(JsonConvert.SerializeObject(mESWriteData), _MES);
                                if (result.ret == 1 && result != null)
                                {
                                    RunLog.runLog.InfoMES($@"【入库上报】上传MES成功 托盘码【{readTrayCode.TrayBar_Code}】【JSON】{JsonConvert.SerializeObject(mESWriteData)}");
                                }
                                else
                                {
                                    _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                        .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】上传MES失败 失败信息【{result.data}】")
                                        .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();

                                    RunLog.runLog.InfoMES($@"【入库上报】上传MES失败 失败信息【{result.data}】托盘码【{readTrayCode.TrayBar_Code}】【JSON】{JsonConvert.SerializeObject(mESWriteData)}");
                                    //return false;
                                }
                            }
                            else
                            {
                                if (resultTrayStatus == null)
                                {
                                    _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                    .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】【MES状态异常】")
                                    .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();
                                    RunLog.runLog.InfoMES($@"【MES接口状态异常】托盘码【{readTrayCode.TrayBar_Code}】");
                                    return false;
                                }
                                else
                                {
                                    _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                  .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】【托盘状态异常】托盘状态【{resultTrayStatus.data.trayResultDesc}】")
                                  .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();
                                    RunLog.runLog.InfoMES($@"【入库托盘状态异常】托盘状态【{resultTrayStatus?.data.trayResultDesc}】托盘码【{readTrayCode.TrayBar_Code}】");
                                    return false;
                                }
                            }

                            if (readTrayCode.Station_Plc_No == "A002")
                            {
                                _ControlA002 = "1";
                            }

                            if (readTrayCode.Station_Plc_No == "A006")
                            {
                                _ControlA006 = "1";
                            }
                        }

                        if (barInfo != null)
                        {
                            //入库库存
                            WarehouseIO.AddWarehouseInfo(new WarehouseIO
                            {
                                ID = readTrayCode.TrayBar_Code.Substring(6, 8),
                                barCode = readTrayCode.TrayBar_Code,
                                CreateTime = DateTime.Now,
                                Task_type = "in",
                                BarCodeData = warehouse.MaterialType,
                                WarehouseCode = $"{warehouse.WarehouseCode}-{warehouse.layer}"

                            });
                        }

                        WcsTaskMain wcsTaskMain1 = new WcsTaskMain
                        {
                            Task_Type = "in",
                            TrayBar_Code = readTrayCode.TrayBar_Code,
                            Start_Station = readTrayCode.Station_Plc_No,
                            End_Station = warehouse.WarehouseCode,
                            Current_Station = readTrayCode.Station_Plc_No,
                            EndWMSBinCode = warehouse.layer,
                            WMSEndStation = warehouse.WarehouseCode,
                            MaterialType = material.MaterialType,
                        };
                        _SqlSugarDapper.DB.Insertable(wcsTaskMain1).ExecuteCommand();

                        WarehouseInfo.AddWarehouseInfo(new WarehouseInfo
                        {
                            ID = id,
                            barCode = wcsTaskMain1.TrayBar_Code,
                            index = 999999999,
                            state = (int)StationState.入库占用,
                            CreateTime = DateTime.Now,
                        });

                        _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                            .SetColumns(s => s.Remark == $"")
                            .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();

                        return true;
                    }
                    if (readTrayCode.Station_Plc_No == "A006")
                    {
                        BarCodeInfo barCodeInfo = new BarCodeInfo()
                        {
                            BarCode = readTrayCode.TrayBar_Code
                        };

                        if (_LAY == "0")
                        {
                            _SqlSugarDapper.DB.Insertable(barCodeInfo).ExecuteCommand();
                        }

                        var barInfo = BarCodeInfo.GetBarCodeIsGood(readTrayCode.TrayBar_Code);

                        //截取托盘识别码
                        var IdentificationCode = readTrayCode.TrayBar_Code.Substring(6, 8);

                        var tishenji = readTrayCode.Station_Plc_No == "A002" ? 1 : 2;

                        //根据托盘吗判断是什么物料
                        var material = PalletToMaterial.GeMaterialTypeByPallet(IdentificationCode);

                        if (material == null)
                        {
                            _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】未找到托盘对应的物料类型")
                                .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();

                            RunLog.runLog.Warning($@"未找到托盘对应的物料类型 托盘码【{readTrayCode.TrayBar_Code}】");
                            return false;
                        }
                        //bool flag = false;
                        Warehouse warehouse;
                        if (barInfo == null)
                        {
                            //没有托盘信息就是空托盘
                            //根据物料号查询这个物料在那个仓库的第几层
                            warehouse = Warehouse.GetWarehouseByMaterialTypeIn(0, material.MaterialType, "9001");
                            BarCodeInfo.DeleteBarCodeInfo(readTrayCode.TrayBar_Code);
                        }
                        else
                        {
                            /*
                             * Dev_Code A002 标识
                             * Read_Block A006 标识
                             */
                            var flag2 = _SqlSugarDapper.DB.Queryable<WcsDevPlc>().Where(w => w.PLC_Name.Contains("托盘库堆垛机"))
                                    .First().Read_Block;

                            if (flag2 == "false")
                            {
                                //根据物料号查询这个物料在那个仓库的第几层
                                warehouse = Warehouse.GetWarehouseByMaterialTypeIn(1, material.MaterialType, "9001");
                                BarCodeInfo.DeleteBarCodeInfo(readTrayCode.TrayBar_Code);
                                _SqlSugarDapper.DB.Updateable<WcsDevPlc>()
                                     .SetColumns(w => w.Read_Block == "true")
                                     .Where(w => w.PLC_Name.Contains("托盘库堆垛机"))
                                     .ExecuteCommand();
                            }
                            else
                            {
                                //根据物料号查询这个物料在那个仓库的第几层
                                warehouse = Warehouse.GetWarehouseByMaterialTypeIn(1, material.MaterialType, "9002");
                                BarCodeInfo.DeleteBarCodeInfo(readTrayCode.TrayBar_Code);
                                _SqlSugarDapper.DB.Updateable<WcsDevPlc>()
                                     .SetColumns(w => w.Read_Block == "false")
                                     .Where(w => w.PLC_Name.Contains("托盘库堆垛机"))
                                     .ExecuteCommand();
                            }
                        }

                        //找到一层如满料的并且没有物料的层
                        if (warehouse == null)
                        {
                            //var warehourseId = _SqlSugarDapper.DB.Queryable<Warehouse>()
                            //     .Where(w => w.IsFullMaterial == 1 && w.IsIN == 1 && w.IsOUT == 1 && SqlFunc.Subqueryable<WarehouseInfo>().Where(x => x.ID == w.ID).NotAny()).First();

                            //if (warehourseId == null)
                            //{
                            //    _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                            //    .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】没有库存")
                            //    .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();

                            //    RunLog.runLog.Warning($@"物料【{material.MaterialType}】没有库存 托盘码【{readTrayCode.TrayBar_Code}】");
                            //    return false;
                            //}

                            ////开辟新层
                            //_SqlSugarDapper.DB.Updateable<Warehouse>()
                            //    .SetColumns(w => w.MaterialType == material.MaterialType)
                            //    .SetColumns(w => w.IsIN == 1)
                            //    .SetColumns(w => w.IsOUT == 1)
                            //    .Where(w => w.ID == warehourseId.ID)
                            //    .ExecuteCommand();

                            //RunLog.runLog.Warning($@"物料【{material.MaterialType}】开辟新的库存【{warehourseId.ID}】");
                            //return false;

                            _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】没有库存")
                                .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();

                            RunLog.runLog.Warning($@"物料【{material.MaterialType}】没有库存 托盘码【{readTrayCode.TrayBar_Code}】");
                            return false;
                        }

                        string id = $"{warehouse.WarehouseCode}-{warehouse.layer}";

                        //满料
                        if (barInfo != null && (_ControlA006 == "1" && readTrayCode.Station_Plc_No == "A006" || _ControlA002 == "1" && readTrayCode.Station_Plc_No == "A002"))
                        {
                            var resultTrayStatus = HttpRequest.httpRequest.WebGetRequestMES(readTrayCode.TrayBar_Code, "http://10.3.15.130:8090/apis/Acc/ProductProcess/TrayStatus?trayCode=");
                            if (resultTrayStatus?.data.trayResultDesc == "制芯下料")
                            {
                                //调用接口告诉MES当前托盘入库成功
                                //入库上报MES
                                MESWriteData mESWriteData = new MESWriteData()
                                {
                                    MachineId = 129051,
                                    MachineType = 501,
                                    ActionTypeId = 1,
                                    data = new Data { TrayCode = readTrayCode.TrayBar_Code }
                                };
                                var result = HttpRequest.httpRequest.WebPostRequestMES(JsonConvert.SerializeObject(mESWriteData), _MES);
                                if (result.ret == 1 && result != null)
                                {
                                    RunLog.runLog.InfoMES($@"【入库上报】上传MES成功 托盘码【{readTrayCode.TrayBar_Code}】【JSON】{JsonConvert.SerializeObject(mESWriteData)}");
                                }
                                else
                                {
                                    _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                        .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】上传MES失败 失败信息【{result.data}】")
                                        .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();

                                    RunLog.runLog.InfoMES($@"【入库上报】上传MES失败 失败信息【{result.data}】托盘码【{readTrayCode.TrayBar_Code}】【JSON】{JsonConvert.SerializeObject(mESWriteData)}");
                                    return false;
                                }
                            }
                            else
                            {
                                if (resultTrayStatus == null)
                                {
                                    _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                    .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】【MES状态异常】")
                                    .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();
                                    RunLog.runLog.InfoMES($@"【MES接口状态异常】托盘码【{readTrayCode.TrayBar_Code}】");
                                    return false;
                                }
                                else
                                {
                                    _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                                  .SetColumns(s => s.Remark == $"【{tishenji}号提升机托盘】【托盘状态异常】托盘状态【{resultTrayStatus.data.trayResultDesc}】")
                                  .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();
                                    RunLog.runLog.InfoMES($@"【入库托盘状态异常】托盘状态【{resultTrayStatus?.data.trayResultDesc}】托盘码【{readTrayCode.TrayBar_Code}】");
                                    return false;
                                }
                            }

                            if (readTrayCode.Station_Plc_No == "A002")
                            {
                                _ControlA002 = "1";
                            }

                            if (readTrayCode.Station_Plc_No == "A006")
                            {
                                _ControlA006 = "1";
                            }
                        }

                        if (barInfo != null)
                        {
                            //入库库存
                            WarehouseIO.AddWarehouseInfo(new WarehouseIO
                            {
                                ID = readTrayCode.TrayBar_Code.Substring(6, 8),
                                barCode = readTrayCode.TrayBar_Code,
                                CreateTime = DateTime.Now,
                                Task_type = "in",
                                BarCodeData = warehouse.MaterialType,
                                WarehouseCode = $"{warehouse.WarehouseCode}-{warehouse.layer}"
                            });
                        }

                        WcsTaskMain wcsTaskMain1 = new WcsTaskMain
                        {
                            Task_Type = "in",
                            TrayBar_Code = readTrayCode.TrayBar_Code,
                            Start_Station = readTrayCode.Station_Plc_No,
                            End_Station = warehouse.WarehouseCode,
                            Current_Station = readTrayCode.Station_Plc_No,
                            EndWMSBinCode = warehouse.layer,
                            WMSEndStation = warehouse.WarehouseCode,
                            MaterialType = material.MaterialType,
                        };
                        _SqlSugarDapper.DB.Insertable(wcsTaskMain1).ExecuteCommand();

                        WarehouseInfo.AddWarehouseInfo(new WarehouseInfo
                        {
                            ID = id,
                            barCode = wcsTaskMain1.TrayBar_Code,
                            index = 999999999,
                            state = (int)StationState.入库占用,
                            CreateTime = DateTime.Now,
                        });

                        _SqlSugarDapper.DB.Updateable<WcsReadTrayCode>()
                            .SetColumns(s => s.Remark == $"")
                            .Where(w => w.Station_Plc_No == readTrayCode.Station_Plc_No).ExecuteCommand();

                        return true;
                    }
                    return false;
                }
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($@"【 {_modular} 】异常信息【{ex.Message}】【{ex.StackTrace}】");
                return false;
            }
        }

        /// <summary>
        /// 删除任务并加入历史记录
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="TaskCode"></param>
        public void DeleteMainTask(string id, string TaskTips)
        {
            try
            {
                //更新主任务提示
                _SqlSugarDapper.DB.Updateable<WcsTaskMain>()
                    .SetColumns(w => w.TaskTips == TaskTips)
                    .Where(w => w.Id == id)
                    .ExecuteCommand();

                //添加历史记录
                _SqlSugarDapper.DB.Insertable<WcsZBKTaskMain>(
                    _SqlSugarDapper.DB.Queryable<WcsTaskMain>().Where(w => w.Id == id).First())
                    .ExecuteCommand();

                //删除任务
                _SqlSugarDapper.DB.Deleteable<WcsTaskMain>()
                       .Where(w => w.Id == id)
                       .ExecuteCommand();
            }
            catch (Exception ex)
            {
                RunLog.runLog.Error($@"【 {_modular} 】异常信息【{ex.Message}】【{ex.StackTrace}】");
            }
        }
    }
}

